﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Linq;
using NHibernate.Criterion;
using WebPattern.DataAccess;
using WebPattern.Core.Logger;

namespace WebPattern.Core
{
    public class UserRepository : Repository<long, User>
    {
        #region Logger
        private CustomLog4net _customLogger = new CustomLog4net(Logger);
        private CustomLog4net CLogger
        {
            get { return _customLogger; }
        }
        #endregion
        
        #region Constructors
        public UserRepository() : base(typeof(UserRepository)) { }
        public UserRepository(ISession session) : base(session, typeof(UserRepository)) { }
        #endregion

        #region Select
        public User GetUserByName(string userName, string appName)
        {
            //if (string.IsNullOrEmpty(appName)) appName = "dd";

            return Session.Query<User>()
                .Where(q => q.UserName == userName)
                .Where(q => q.ApplicationName == appName)
                .FirstOrDefault();
        }
        public IList<User> GetAllUsers(int pageIndex, int pageSize, string appName)
        {

            int rowIndexStart = pageIndex > 0 ? (int)(((pageIndex - 1) * pageSize) + 1) : 1;
            int rowIndexStop = pageIndex > 0 ? (int)((pageIndex) * pageSize) : (int)pageSize;

            return Session.Query<User>()
                .Where(q=>q.ApplicationName == appName)
                .Skip(rowIndexStart - 1).Take(rowIndexStop + 1 - rowIndexStart).ToList();
        }
        public IList<User> FindUsersByName(string userNameToMatch, int pageIndex, int pageSize, string appName)
        {
            int rowIndexStart = pageIndex > 0 ? (int)(((pageIndex - 1) * pageSize) + 1) : 1;
            int rowIndexStop = pageIndex > 0 ? (int)((pageIndex) * pageSize) : (int)pageSize;

            return Session.Query<User>()
                .Where(q=>q.ApplicationName == appName)
                .Where(q=>q.UserName.IsLike(userNameToMatch,MatchMode.Anywhere))
                .Skip(rowIndexStart - 1).Take(rowIndexStop + 1 - rowIndexStart).ToList();
        }
        public IList<User> FindUsersByEmail(string email, int pageIndex, int pageSize, string appName)
        {
            int rowIndexStart = pageIndex > 0 ? (int)(((pageIndex - 1) * pageSize) + 1) : 1;
            int rowIndexStop = pageIndex > 0 ? (int)((pageIndex) * pageSize) : (int)pageSize;

            return Session.Query<User>()
                .Where(q => q.ApplicationName == appName)
                .Where(q => q.Email.IsLike(email, MatchMode.Anywhere))
                .Skip(rowIndexStart - 1).Take(rowIndexStop + 1 - rowIndexStart).ToList();
        }
        public string GetUsernameByEmail(string email, string appName)
        {
            return Session.Query<User>()
                .Where(q => q.ApplicationName == appName)
                .Where(q => q.Email == email)
                .FirstOrDefault().UserName;
        }
        public int GetNumberOfUsersOnline(DateTime compareTime, string appName)
        {
            return Session.Query<User>()
                .Where(q => q.ApplicationName == appName)
                .Where(q => q.LastActivityDate >= compareTime)
                .Count();
        }
        public IList<User> GetUsersOnline(DateTime compareTime, string appName)
        {
            return Session.Query<User>()
                .Where(q => q.ApplicationName == appName)
                .Where(q => q.LastActivityDate >= compareTime)
                .ToList();
        }
        #endregion

        #region Delete
        public void Delete(User user)
        {
            Delete(user.Id);
        }
        #endregion

        #region Security
        /// <summary>
        /// Gets the password.
        /// </summary>
        /// <param name="username">The username.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public string GetPassword(string username)
        {
            return Session.Query<User>()
                .Where(u => u.UserName == username)
                .Select(u => u.Password).First();
        }
        /// <summary>
        /// Gets the password.
        /// </summary>
        /// <param name="UserId">The user id.</param>
        /// <returns></returns>
        /// <remarks></remarks>
        public string GetPassword(long UserId)
        {
            return Session.Query<User>()
                .Where(u => u.Id == UserId)
                .Select(u => u.Password).First();
        }
        #endregion
    }
}
